/*
 *  JDiv - API for Multimedia Application
 *  http://jdiv.sourceforge.net 
 *  ------------------------------------
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

package com.jdiv.physics;

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Joint;
import com.badlogic.gdx.physics.box2d.joints.WheelJoint;
import com.badlogic.gdx.physics.box2d.joints.WheelJointDef;
import com.jdiv.Const;
import com.jdiv.kernel.JDivSystem;

/** Wheel joint. This requires defining a line of motion using an axis and an anchor point. The definition uses local anchor points and a local axis so that the initial configuration can violate the constraint slightly. The joint translation is zero when the local anchor points coincide in world space. Using local anchors and a local axis helps when saving and loading a game. */

public class JointWheel {
		
		WheelJointDef jointDef;
		Joint joint;
		
		/**
		 * Constructor of JointWheel.
		 * @param bodyA Body of object A.
		 * @param bodyB Body of object B.
		 * @param collideConnected Sets if they collide with each other.
		 */
		 
		public JointWheel( Body bodyA, Body bodyB, boolean collideConnected ){
			
		 jointDef = new WheelJointDef();
		 
		 joint = null;
		 
		 init( bodyA, bodyB, collideConnected );
		}
		
		/**
		 * Initialize the bodies.
		 * @param bodyA Body of object A.
		 * @param bodyB Body of object B.
		 * @param collideConnected Sets if they collide with each other.
		 */
		
	   public void init ( Body bodyA, Body bodyB, boolean collideConnected ){
			
			if( joint != null ) return;
			
			jointDef.bodyA = bodyA;
			jointDef.bodyB = bodyB;
			jointDef.collideConnected = collideConnected;
		}
	   
	   /**
	    * Sets the pivot point from object A.
	    * @param x Coordinate X.
	    * @param y Coordinate Y.
	    */
		 
		public void setAnchorA( float x, float y ){
		 jointDef.localAnchorA.set(x * Const.BOX2D_SCREEN_TO_PHYSICS, 
				                   y * Const.BOX2D_SCREEN_TO_PHYSICS);
		}
		
		/**
		    * Sets the pivot point from object B.
		    * @param x Coordinate X.
		    * @param y Coordinate Y.
		    */
		 
		public void setAnchorB( float x, float y ){
		 jointDef.localAnchorB.set(x * Const.BOX2D_SCREEN_TO_PHYSICS, 
				                   y * Const.BOX2D_SCREEN_TO_PHYSICS);
		}
		
		/**
		    * Sets the local axis from object A.
		    * @param x Coordinate X.
		    * @param y Coordinate Y.
		    */
		
		public void setLocalAxisA( float x, float y ){
			 jointDef.localAxisA.set(x * Const.BOX2D_SCREEN_TO_PHYSICS, 
					                 y * Const.BOX2D_SCREEN_TO_PHYSICS);
		}
		
		/**
		 * Enable the joint motor.
		 * @param maxMotorTorque The maximum motor torque, usually in N-m. 
		 * @param speed The desired motor speed in angle per second. 
		 */
		
		public void setMotor( float maxMotorTorque, float speed ){
			 jointDef.enableMotor    = true;
			 jointDef.maxMotorTorque = maxMotorTorque;
			 jointDef.motorSpeed     = speed * MathUtils.degreesToRadians;
		}
		
		/**
		 * @param dampingRatio Suspension damping ratio, one indicates critical damping. 
		 */
		 
		public void setDampingRatio( float dampingRatio ){
			jointDef.dampingRatio = dampingRatio;
		}
		
		/**
		 * @param frequencyHz Suspension frequency, zero indicates no suspension.
		 */
		
		public void setFrequencyHz( float frequencyHz ){
			jointDef.frequencyHz = frequencyHz;
		}
		
		/**
		 * @return Gets WheelJoint of LibGdx.
		 */
		
		public WheelJoint getWheelJoint(){
			return (WheelJoint)joint;
		}
		
		/**
		 * Add the joint to the physical world.
		 * @return The joint in the physical world.
		 */
		 
		public Joint addToWorld(){
		 if( joint != null ) return joint;
		 
		 if( JDivSystem.box2dWorld != null )	
		  joint = JDivSystem.box2dWorld.createJoint(jointDef);
		 
		 return joint;
		}
		
		/** Delete the joint in the physical world. */
		
		public void delete(){
			if( (JDivSystem.box2dWorld == null) || (joint == null) ) return;
			
			JDivSystem.box2dWorld.destroyJoint(joint);
			joint = null;
		}
	}
